# -*- coding: utf-8 -*-

import codecs
import types
from utils.util import *
from utils import chars


def split_smart(word, part_list, special_list):
    seq = [word]
    found = True
    while found:
        found = False
#        print '>',seq
        for w in seq:
#            print w,'.',
            for l in special_list:
                if l in w and not l is w:
                    seq[seq.index(w)] = [w[:w.index(l)],l,w[w.index(l)+len(l):]]
                    seq = trimList(flatten(seq))
                    found = True
                    break
            if(found): break
    final_seq = []
    for w in seq:
        if(w not in special_list):
            final_seq.append(split_from_list(w, part_list))
        else:
            final_seq.append(w)
    return trimList(flatten(final_seq))
                
def test_smart():
    word = 'sistitho'
    part_list = ['si','st','it','ho','s','i','t','h','o']
    special_list = ['th']
    print split_smart(word, part_list, special_list)
    

def split_from_list(word, parts_list):
    seq = []
    while len(word) > 0:
        found = False
        for l in parts_list:
            if word.startswith(l):
#                print l,                
                seq.append(l)
                word = word[len(l):]
                found = True
                break
        if not found:
            #print 'UNKNOWN REST:', word
            return None
                
#        print 'UNKNOWN REST:', word
    return seq

def test_split():
    list = ['s', 'o' , 'es','or','ti','a']
    list.sort(key=len, reverse=True)
    print split_from_list('orestis',list)
            
            

def test():
    file = codecs.open('data/word_list.txt','r','utf-8')  
    mismatch = 0
    len_mismatch = 0
    total = 0
    for line in file:  
        total +=1
        [greeklish, greek, rank, dummy]=line.split(' - ')
        grkl_seq = split_word_grkl(greeklish.lower())
        gr_seq = split_word_gr( greek.lower().translate(chars.simple_ch))
        seq = align3(greeklish.lower(), greek.lower().translate(chars.simple_ch))
        if seq!= None:
            if len(grkl_seq) != len(gr_seq):
               print 'LENGTH MISMATCH'
               printSeq(grkl_seq)
               printSeq(gr_seq)
               printSeq2(seq)
               print '---'
               len_mismatch +=1
            else:
                seq2 = []
                for i in range(0,len(grkl_seq)):
                    seq2.append((grkl_seq[i],gr_seq[i]))
                if(seq != seq2):
                    print 'MISMATCH'
                    printSeq(grkl_seq)
                    printSeq(gr_seq)
                    printSeq2(seq)
                    print '---'
                    mismatch +=1     
    print 'Mismatches:',mismatch
    print 'Lentgh Mismatches:',len_mismatch
    print 'Total:',total
                    
            

def demo():
    file = codecs.open('data/word_list.txt','r','utf-8')

    for line in file:
        [greeklish, greek, rank, dummy]=line.split(' - ')
        align3(greeklish.lower(), greek.lower().translate(chars.simple_ch))
        
def demo5():
    file = codecs.open('data/word_list.txt','r','utf-8')

    for line in file:
        [greeklish, greek, rank, dummy]=line.split(' - ')
        grkl_seq = split_word_grkl(greeklish.lower())
        for c in grkl_seq:
            print c.encode('utf-8'),'-',
        print ''
        gr_seq = split_word_gr( greek.lower().translate(chars.simple_ch))
        for c in gr_seq:
            print c.encode('utf-8'),'-',
        print ''
        
def demo6():

    for greeklish,greek in prob_words:
        align3(greeklish, greek)
        grkl_seq = split_word_grkl(greeklish.lower())
        for c in grkl_seq:
            print c.encode('utf-8'),'-',
        print ''
        gr_seq = split_word_gr( greek.lower().translate(chars.simple_ch))
        for c in gr_seq:
            print c.encode('utf-8'),'-',
        print ''
        
def split_word_gr(greek):
    sequence = []
    idx_gr = 0
    while idx_gr<len(greek):
        syll_gr = greek[idx_gr:idx_gr+2]
        if syll_gr in chars.dipthongs_rev:
            sequence.append(syll_gr)
            idx_gr+=2
            continue
        sequence.append(greek[idx_gr])
        idx_gr+=1
      
    return group_parts(sequence)

def split_word_gr2(greek):
    sequence = []
    for c in greek:
        sequence.append(c)
    return sequence
        

def split_word_grkl(greeklish):
    sequence = []
    idx_grkl = 0
    while idx_grkl<len(greeklish):
        syll_grkl = greeklish[idx_grkl:idx_grkl+2]
        if syll_grkl in chars.dipthongs:
            sequence.append(syll_grkl)
            idx_grkl+=2
            continue
        sequence.append(greeklish[idx_grkl])
        idx_grkl+=1

    return group_parts(sequence)

def group_parts2(sequence):
    sequence2=[]
    i = 0
    grkl1 = None;grkl2=None;gr1=None;gr2=None
    while(i<len(sequence)-1):
        grkl1,gr1 = sequence[i]
        grkl2,gr2 = sequence[i+1]
        if(len(grkl1)==1 and len(grkl2)==1 and len(gr1)==1 and len(gr2)==1):
            sequence2.append((grkl1+grkl2,gr1+gr2))
            grkl1 = None;grkl2=None;gr1=None;gr2=None
        else:
            sequence2.append((grkl1,gr1))
            i-=1
        i+=2
    try:
        grkl,gr = sequence[i]
        sequence2.append((grkl,gr))
    except:
        pass
#    if not grkl2 is None: sequence2.append((grkl2,gr2))
#    elif len(sequence)%2==1: sequence2.append(sequence[-1])
    return sequence2
                    
                                        
                
# TODO this must take into account the special chars, in greek
def group_parts(sequence):
#    printSeq(sequence)
    sequence2 = []
    prev = None
    for c in sequence:
        if prev :
            if len(prev)==2:
                sequence2.append(prev)
                prev = c
            else:
                if len(c)==1 and c not in chars.greek_special and not prev in chars.greek_special \
                             and c not in chars.greeklish_special and not prev in chars.greeklish_special:
                    prev+=(c)
                else:
                    sequence2.append(prev)
                    prev = c
        else: prev=c
    sequence2.append(prev)
#    printSeq(sequence2)
    return sequence2
        
def align3(greeklish, greek):
#    print greeklish, greek
    sequence = []
#    greeklish_copy = greeklish
#    greek_copy = greek
#    gr_list = range(0, len(greek_copy))
#    grkl_list = range(0, len(greeklish_copy))
    idx_grkl = 0
    idx_gr = 0
    while idx_grkl<len(greeklish) and idx_gr<len(greek):
        syll_grkl = greeklish[idx_grkl:idx_grkl+2]
        syll_gr = greek[idx_gr:idx_gr+2]
        if syll_grkl in chars.dipthongs:
            syll_gr = greek[idx_gr]
            syll_gr2 = greek[idx_gr:idx_gr+2]
            if syll_gr2 == chars.dipthongs_normal.get(syll_grkl, None):
                sequence.append((syll_grkl, syll_gr2))
                idx_gr +=2
                idx_grkl +=2
                continue
            elif syll_gr == chars.dipthongs[syll_grkl]: # WE GOT MATCH!
                sequence.append((syll_grkl, syll_gr))
                idx_grkl +=2
                idx_gr +=1
                continue
                
        elif syll_gr in chars.dipthongs_rev:
            syll_grkl = greeklish[idx_grkl]
            syll_grkl2 = greeklish[idx_grkl:idx_grkl+2]
            if syll_grkl2 == chars.dipthongs_rev_normal.get(syll_gr, None):
                sequence.append((syll_grkl2, syll_gr))
                idx_gr +=2
                idx_grkl +=2
                continue
            elif syll_grkl == chars.dipthongs_rev[syll_gr] : # WE GOT MATCH!
                sequence.append((syll_grkl, syll_gr))
                idx_gr +=2
                idx_grkl +=1
                continue
        
        sequence.append((greeklish[idx_grkl],greek[idx_gr]))
        idx_grkl +=1
        idx_gr +=1    
    if idx_gr<len(greek) or idx_grkl<len(greeklish): 
        print 'POSSIBLE MISALIGNMENT ON',greeklish,greek.encode('utf-8')
        return None
    
#    printSeq2(sequence)
    sequence2=group_parts2(sequence)
#    printSeq2(sequence2)
    
    
#    for grkl,gr in sequence:
#        print grkl,' - ', gr
    return sequence2
            
    
#    for key in chars.dipthongs:
#        if key in greeklish_copy and chars.dipthongs[key] in greek_copy:
#            grkl_index = greeklish.index(key)
#            gr_index = greek.index[chars.dipthongs[key]]
#            if abs(grkl_index-gr_index)<2: # same neighborhood
#                map[(grkl_index,grkl_index+1)]=gr_index
#                grkl_list.remove(grkl_index)
#                grkl_list.remove(grkl_index+1)                
#                gr_list.remove(gr_index)
#                greeklish_copy = greeklish_copy.replace(key,'')
#                greek_copy = greek_copy.replace(chars.dipthongs[key],'')
#                
#                
#                
#    pass
        
        

def demo3():
    align3('thrilos',u'θρύλος')
    align3('thrithlos',u'θρύθλος')    
    align3('thrithos',u'θρύθος')   
    
def demo4():
    align3('gh',u'γή')     
    align3('gh',u'γη')         

def demo2():
    align3('orestis',u'ορέστης')
    align3('gianis',u'γιάννης')
    align3('gianhs',u'γιάννης')
    align3('giannis',u'γιάννης')        
    align3('oraios',u'ωραίος')
    align3('falaina',u'φάλαινα')    
    align3('falaina',u'φάλαινα')   
    align3('falaina',u'φάλαινα')   
    align3('falaina',u'φάλαινα')   
    align3('thanasis',u'θανάσης')           
    align3('ksyrafi',u'ξυράφι')   
    align3('3yrafi',u'ξυράφι')   
    align3('ethiksa',u'έθιξα')   
    align3('thylhko',u'θυληκό')           
    align3('proedros',u'πρόεδρος')     
    align3('arougalos',u'αρούγκαλος')     
    align3('arougkalos',u'αρούγκαλος')    
    align3('amplaoublas',u'αμπλαούβλας')    
    align3('amplaoublas',u'αμπλαούμπλας')        
    align3('almpanis',u'αλμπάνης')        
    align3('albanis',u'αλμπάνης')        
    align3('gampros',u'γαμπρός')        
    align3('gabros',u'γαμπρός')            
    align3('gabros',u'γαβρος')            
    align3('gabros',u'γαυρός')                   
    align3('ginete',u'γίνεται')            
    align3('thrhsh',u'τήρηση') 
    align3('sabaoth',u'σαββαώθ')  
    align3('diathesi', u'διαθεση') 
    align3('athanatos', u'αθανατος')    
    

            
#def demo_split():
#    print split_word2('test')
#    print split_word2('orestis')
#    print split_word2('frosara')
#    print split_word2('malakas')
#    print split_word2('malaka')        
#    print split_word2('kala')         
#    print split_word2(u'ορέστης')    
            
        
    

def split_word(word, f_1, f_2, special_chars=''):
    parts = []
    buf_chars = []
    word = unicode(word)
    word = word + u''
    change = True
    special = []
    for c in word:
        if c in special_chars: 
            if not special:
                special.append(c)
                               
            else:
                special.append(c)
                buf_chars += special
                if change: change = not f_1(special[0]) 
                else: change = f_2(special[0])
                special = []
                continue
                    

            
        if change:
            if(f_1(c)):
                change = False
                parts.append(u''.join(buf_chars))
                if len(buf_chars)>3:print 'Big length!', u''.join(buf_chars).encode('utf-8')
                buf_chars = []
            else: change = True
        else:
            if f_2(c):
                change =  True
                parts .append(u''.join(buf_chars))
                if len(buf_chars)>3:print 'Big length!', u''.join(buf_chars).encode('utf-8')                
                buf_chars = []
            else: change = False
        if not special:
            buf_chars += c
    parts.append( u''.join(buf_chars))
    if parts[0] == u'':
        parts = parts[1:]
    return parts
                

def split_greek_word(greek):
    return split_word(greek, isGreekCons, isGreekVowel)

def split_greeklish_word(greeklish):
    return split_word(greeklish, isGreeklishCons, isGreeklishVowel)


 
def align(greeklish, greek):
    """Definite alignment chars are:
     d - δ, z - ζ, 
    """
    if(not greeklish.isalnum()): return None
    assert (type(greek)==types.UnicodeType)
    align_dict = {u'δ' : 'd',
                  u'ζ' : 'z',
                  u'λ' : 'l',
                  u'ρ' : 'r',
                  u'φ' : 'f',
                  }
    #how to do this ? read the chars. if change from vowel to consonant or from consonant to vowel, align the chars
#------------------------------------------------------------------------------ 
    #greek
    parts_gr = split_greek_word(greek)
    parts_grkl = split_greeklish_word(greeklish)
#    print parts
    
    
    #This part sucks!
    diff = False
    while(len(parts_gr)!=len(parts_grkl) and not diff):
        print 'Different part length:' 
        print u'-'.join(parts_gr).encode('utf-8')
        print '-'.join(parts_grkl).encode('utf-8')
        if u'θ' in greek and 'th' in 'th':
            if greeklish.index('th') == greek.index(u'θ'):
                if True: 
                    print 'Retrying'
                    parts_gr = split_word(greek, isGreekCons, isGreekVowel)
                    parts_grkl = split_word(greeklish, isGreeklishCons, isGreeklishVowel, 'th') 
                    print u'-'.join(parts_gr).encode('utf-8')
                    print '-'.join(parts_grkl).encode('utf-8')  
                    continue
            else: diff = True
        return None
    
   
    
    sequence = []
    for i in range(0,len(parts_gr)):
        sequence.append((parts_grkl[i],parts_gr[i]))
    
#    print '-'.join(parts_grkl).encode('utf-8')
#    print '-'.join(parts_gr).encode('utf-8')
#    print sequence
    
    return sequence
       
        
prob_words = [('koynoypioy',u'κουνουπιου'),  
              ('katouro',u'κατουρο'), 
              ('phenomenika',u'φαινομενικα'), 
              ('ompreles',u'ομπρελες'), 
              ('agaphmeno',u'αγαπημενο'),
              ('sobareuete',u'σοβαρευετε'),
              ('athanatos', u'αθανατος') ,('diathesi', u'διαθεση') 
              ]

if __name__ == '__main__':
#    demo()
#    demo2()
#    demo3()
#    demo4()
#    demo5()
    test_smart()

    